#ifndef ThreadQueue_h_2236
#define ThreadQueue_h_2236 

#include "WinCriticalSection.h"
#include "Semaphore.h"
#include <queue>
#include <limits>
#include <list>

template< typename _T >
class ThreadQueue
{
public:
	typedef typename std::queue<_T>::size_type size_type;

	//ThreadQueue( size_type maxSize = std::numeric_limits< size_type >::max() ):
	ThreadQueue( size_type maxSize = 100 ):
	m_maxSize( maxSize )
	{

	}

	bool push(const _T& val) 
	{ 
		Mutex mutex (m_cs);

		if ( m_queue.size() >= m_maxSize )
			return false;

		m_queue.push(val); 

		m_sem.setUp();

		return true;
	}


	bool pop(_T& val, int time = INFINITE)
	{
		m_sem.wait(time);

		Mutex mutex (m_cs);
		if( !m_queue.empty() ) 
		{
			val = m_queue.front();  
			m_queue.pop();
			return true; 
		}
		return false;
	}

	void clear()
	{
		Mutex mutex (m_cs);
		while (!m_queue.empty()) 
			m_queue.pop();
	}

	int size() const
	{
		Mutex mutex (m_cs);
		return m_queue.size();
	}

	int maxSize() const
	{
		return m_maxSize;
	}

	virtual ~ThreadQueue()
	{
	}
private:
	std::queue<_T> m_queue;//synchronizeed
	size_type m_maxSize;
	mutable WinCriticalSection m_cs;
	Semaphore m_sem;

};

template< typename _P >
class ThreadList
{
public:
	typedef typename std::list<_P>::size_type size_type;

	//ThreadQueue( size_type maxSize = std::numeric_limits< size_type >::max() ):
	ThreadList( size_type maxSize = 100000 ):
	m_maxSize( maxSize )
	{

	}

	bool push(const _P& val) 
	{ 
		Mutex mutex (m_cs);
		if ( m_queue.size() >= m_maxSize )
			return false;
		m_queue.push_back(val);
		m_sem.setUp();
		return true;
	}

	bool pop(_P& val, int time = INFINITE)
	{
		m_sem.wait(time);
		Mutex mutex (m_cs);
		if( !m_queue.empty() ) 
		{
			val = m_queue.front();
			m_queue.pop_front();
			return true; 
		}
		return false;
	}

	bool get(int index, _P& val, int time = INFINITE )
	{
		Mutex mutex (m_cs);
		if( !m_queue.empty() && index < m_queue.size() ) 
		{
			list<_P>::iterator it_value;
			it_value = m_queue.begin();
			for( int i=0; i < index ; i ++ )	it_value ++;

			if( it_value == m_queue.end() ) return false;
			val = *it_value;
			return true; 
		}
		return false;
	}

	void remove( int index , int time = INFINITE)
	{
		Mutex mutex (m_cs);
		if( !m_queue.empty() && index < m_queue.size() ) 
		{
			list<_P>::iterator it_value;
			it_value = m_queue.begin();
			for( int i=0; i < index ; i ++ )	it_value ++;

			if( it_value == m_queue.end() ) return;
			m_queue.erase( it_value );
			return; 
		}
		return;
	}

	void remove( _P& val , int time = INFINITE)
	{
		Mutex mutex (m_cs);
		list<_P>::iterator it_value;
		it_value = m_queue.begin();
		while( it_value != m_queue.end() )
		{
			if( *it_value == val )
			{
				m_queue.erase( it_value );
				return;
			}
			it_value ++;
		}
		return; 
	}

	void clear()
	{
		Mutex mutex (m_cs);
		while (!m_queue.empty()) 
			m_queue.pop();
	}

	int size() const
	{
		Mutex mutex (m_cs);
		return m_queue.size();
	}

	int maxSize() const
	{
		return m_maxSize;
	}

	~ThreadList()
	{
	}
public:
	std::list<_P>				m_queue;//synchronizeed
	size_type					m_maxSize;
	mutable WinCriticalSection	m_cs;
	Semaphore					m_sem;

};

#endif //ThreadQueue_h_2236